package parking;

import parking.entity.Car;
import parking.entity.Ticket;
import parking.exception.InvalidTicketException;
import parking.exception.ParkLotIsFullException;
import parking.service.IPark;
import parking.service.ParkReport;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author daiqing.chen
 */
public class ParkLot implements IPark, ParkReport {
    /**
     * 车场最大容量
     */
    protected int capacity;

    /**
     * 停车位
     */
    protected Map<Ticket, Car> spaces;


    public ParkLot(int capacity){
        this.capacity = capacity;
        spaces = new HashMap<Ticket, Car>(capacity);
    }

    /**
     * 停车
     * @param car 车
     * @return  停车票
     */
    @Override
    public Ticket park(Car car) {
        if(!hasSpace()){
            throw new ParkLotIsFullException();
        }
        Ticket ticket = new Ticket();
        this.spaces.put(ticket,car);
        return ticket;
    }

    /**
     * 取车
     * @param ticket 停车票
     * @return  车
     */
    @Override
    public Car take(Ticket ticket){
        if(!isValidTicket(ticket)){
            throw new InvalidTicketException();
        }
        return this.spaces.remove(ticket);
    }

    public Boolean hasSpace(){
        return this.capacity > this.spaces.size();
    }

    public Boolean isValidTicket(Ticket ticket){
        return this.spaces.containsKey(ticket);
    }

    public int surplusSpace(){
        return this.capacity-this.spaces.size();
    }

    public double vacancyRate(){
        return (double) surplusSpace() / (double) this.capacity;
    }

    /*public int getCapacity(){
        return capacity;
    }*/

    public Map<Ticket, Car> getSpaces() {
        return spaces;
    }

    @Override
    public List<ParkReport> getChildren() {
        return Collections.emptyList();
    }

    @Override
    public String getType() {
        return "P";
    }

    @Override
    public int getHasCar() {
        return this.spaces.size();
    }

    @Override
    public int getTotalSpace() {
        return this.capacity;
    }
}
